home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / programming / other / jikes / src / init.cpp < prev    next >
C/C++ Source or Header  |  1999-05-14  |  8KB  |  185 lines

  1. // $Id: init.cpp,v 1.5 1999/02/01 17:43:06 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #include "config.h"
  11. #include "semantic.h"
  12. #include "control.h"
  13.  
  14. void Semantic::ProcessVariableInitializer(AstVariableDeclarator *variable_declarator)
  15. {
  16.     if (! variable_declarator -> variable_initializer_opt)
  17.         return;
  18.  
  19.     VariableSymbol *symbol = variable_declarator -> symbol;
  20.  
  21.     AstArrayInitializer *array_initializer = variable_declarator -> variable_initializer_opt -> ArrayInitializerCast();
  22.     if (array_initializer)
  23.     {
  24.         //
  25.         // This operation may throw OutOfMemoryError
  26.         //
  27.         SymbolSet *exception_set = TryExceptionTableStack().Top();
  28.         if (exception_set)
  29.         {
  30.             exception_set -> AddElement(control.RuntimeException());
  31.             exception_set -> AddElement(control.Error());
  32.         }
  33.         
  34.         ProcessArrayInitializer(array_initializer, symbol -> Type());
  35.     }
  36.     else
  37.     {
  38.         AstExpression *init = (AstExpression *) variable_declarator -> variable_initializer_opt;
  39.         ProcessExpressionOrStringConstant(init);
  40.  
  41.         if (symbol -> Type() != init -> Type() && init -> Type() != control.no_type)
  42.         {
  43.             if (CanAssignmentConvert(symbol -> Type(), init))
  44.             {
  45.                 init = ConvertToType(init, symbol -> Type());
  46.                 variable_declarator -> variable_initializer_opt = init;
  47.             }
  48.             else if (init -> IsConstant() && control.IsSimpleIntegerValueType(init -> Type())
  49.                                           && control.IsSimpleIntegerValueType(symbol -> Type()))
  50.             {
  51.                 if (symbol -> Type() == control.byte_type)
  52.                      ReportSemError(SemanticError::INVALID_BYTE_VALUE,
  53.                                     init -> LeftToken(),
  54.                                     init -> RightToken());
  55.                 else if (symbol -> Type() == control.char_type)
  56.                      ReportSemError(SemanticError::INVALID_CHARACTER_VALUE,
  57.                                     init -> LeftToken(),
  58.                                     init -> RightToken());
  59.                 else ReportSemError(SemanticError::INVALID_SHORT_VALUE,
  60.                                     init -> LeftToken(),
  61.                                     init -> RightToken());
  62.             }
  63.             else
  64.             {
  65.                 ReportSemError(SemanticError::INCOMPATIBLE_TYPE_FOR_ASSIGNMENT,
  66.                                variable_declarator -> LeftToken(),
  67.                                init -> RightToken(),
  68.                                symbol -> Type() -> ContainingPackage() -> PackageName(),
  69.                                symbol -> Type() -> ExternalName(),
  70.                                init -> Type() -> ContainingPackage() -> PackageName(),
  71.                                init -> Type() -> ExternalName());
  72.             }
  73.         }
  74.  
  75.         if (symbol -> ACC_FINAL() && init -> IsConstant())
  76.             symbol -> initial_value = init -> value;
  77.     }
  78.  
  79.     return;
  80. }
  81.  
  82.  
  83. void Semantic::ProcessArrayInitializer(AstArrayInitializer *array_initializer, TypeSymbol *type)
  84. {
  85.     if (! type -> IsArray())
  86.     {
  87.         ReportSemError(SemanticError::INIT_SCALAR_WITH_ARRAY,
  88.                        array_initializer -> LeftToken(),
  89.                        array_initializer -> RightToken(),
  90.                        type -> Name());
  91.     }
  92.     else
  93.     {
  94.         for (int i = 0; i < array_initializer -> NumVariableInitializers(); i++)
  95.         {
  96.             AstArrayInitializer *sub_array_initializer = array_initializer -> VariableInitializer(i) -> ArrayInitializerCast();
  97.             TypeSymbol *array_subtype = type -> ArraySubtype();
  98.             if (sub_array_initializer)
  99.                  ProcessArrayInitializer(sub_array_initializer, array_subtype);
  100.             else
  101.             {
  102.                 AstExpression *init = (AstExpression *) array_initializer -> VariableInitializer(i);
  103.                 ProcessExpressionOrStringConstant(init);
  104.  
  105.                 if (array_subtype != init -> Type())
  106.                 {
  107.                     if (CanAssignmentConvert(array_subtype, init))
  108.                         array_initializer -> VariableInitializer(i) = ConvertToType(init, array_subtype);
  109.                     else if (array_subtype -> IsArray() && init -> Type() -> Primitive())
  110.                     {
  111.                         ReportSemError(SemanticError::INIT_ARRAY_WITH_SCALAR,
  112.                                        init -> LeftToken(),
  113.                                        init -> RightToken(),
  114.                                        array_subtype -> Name());
  115.                     }
  116.                     else if (init -> IsConstant() && control.IsSimpleIntegerValueType(init -> Type())
  117.                                                   && control.IsSimpleIntegerValueType(array_subtype))
  118.                     {
  119.                         if (array_subtype == control.byte_type)
  120.                              ReportSemError(SemanticError::INVALID_BYTE_VALUE,
  121.                                             init -> LeftToken(),
  122.                                             init -> RightToken());
  123.                         else if (array_subtype == control.char_type)
  124.                              ReportSemError(SemanticError::INVALID_CHARACTER_VALUE,
  125.                                             init -> LeftToken(),
  126.                                             init -> RightToken());
  127.                         else ReportSemError(SemanticError::INVALID_SHORT_VALUE,
  128.                                             init -> LeftToken(),
  129.                                             init -> RightToken());
  130.                     }
  131.                     else
  132.                     {
  133.                         ReportSemError(SemanticError::INCOMPATIBLE_TYPE_FOR_INITIALIZATION,
  134.                                        init -> LeftToken(),
  135.                                        init -> RightToken(),
  136.                                        array_subtype -> ContainingPackage() -> PackageName(),
  137.                                        array_subtype -> ExternalName(),
  138.                                        init -> Type() -> ContainingPackage() -> PackageName(),
  139.                                        init -> Type() -> ExternalName());
  140.                     }
  141.                 }
  142.             }
  143.         }
  144.     }
  145.  
  146.     return;
  147. }
  148.  
  149.  
  150. LiteralValue *Semantic::ComputeFinalValue(AstVariableDeclarator *variable_declarator)
  151. {
  152.     LiteralValue *value = NULL;
  153.  
  154.     VariableSymbol *variable = variable_declarator -> symbol;
  155.     TypeSymbol *type = (TypeSymbol *) variable -> owner;
  156.  
  157.     state_stack.Push(type -> semantic_environment);
  158.     if (! error)
  159.         error = new SemanticError(control, source_file_symbol);
  160.     error -> EnteringClone();
  161.     variable_declarator -> pending = true;
  162.  
  163.     AstExpression *init_expr = (AstExpression *) variable_declarator -> variable_initializer_opt;
  164.     AstExpression *init_clone = (AstExpression *) init_expr -> Clone(compilation_unit -> ast_pool);
  165.     ProcessExpressionOrStringConstant(init_clone);
  166.     if (variable -> Type() != init_clone -> Type() && init_clone -> Type() != control.no_type)
  167.     {
  168.         if (CanAssignmentConvert(variable -> Type(), init_clone))
  169.              init_clone = ConvertToType(init_clone, variable -> Type());
  170.         else init_clone -> value = NULL;
  171.     }
  172.     value = init_clone -> value;
  173.  
  174. //
  175. // STG:
  176. //        delete init_clone; // destroy the clone
  177. //
  178.  
  179.     variable_declarator -> pending = false;
  180.     error -> ExitingClone();
  181.     state_stack.Pop();
  182.  
  183.     return value;
  184. }
  185.